import base64
import json
import os
from datetime import datetime

from flask import Flask, request, jsonify, abort, send_from_directory, send_file
from flask_socketio import SocketIO,emit
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS
from spyder.plugins.run.widgets import FILE_DIR
from werkzeug.security import generate_password_hash, check_password_hash
from werkzeug.utils import secure_filename

app = Flask(__name__)
CORS(app)


app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:yt13629520958@localhost:3306/pt_station'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)
socketio = SocketIO(app, cors_allowed_origins='*',async_mode='threading')



class User(db.Model):
    __tablename__ = 'user'
    
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), nullable=False, unique=True)
    password = db.Column(db.String(200), nullable=False)
    email = db.Column(db.String(120), nullable=False)
    role = db.Column(db.String(20), nullable=False, default='USER')
    is_vip = db.Column(db.Boolean, nullable=False, default=False)
    vip_expiry = db.Column(db.DateTime)
    is_banned = db.Column(db.Boolean, nullable=False, default=False)
    ban_reason = db.Column(db.String(255))
    ban_time = db.Column(db.DateTime)
    ban_expiry = db.Column(db.DateTime)
    upload = db.Column(db.String(50), default='0')
    download = db.Column(db.String(50), default='0')
    share_rating = db.Column(db.Float, default=0.0)

    def check_password(self, password):
        return check_password_hash(self.password, password)

    def set_password(self, password):
        self.password = generate_password_hash(password)

    def is_admin(self):
        return self.role == 'ADMIN'

    def is_banned(self):
        if self.is_banned and self.ban_expiry and self.ban_expiry < datetime.utcnow():
            self.is_banned = False
            self.ban_reason = None
            self.ban_time = None
            self.ban_expiry = None
            db.session.commit()
        return self.is_banned


class Message(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    sender_id = db.Column(db.Integer, nullable=False)
    receiver_id = db.Column(db.Integer, nullable=False)
    content = db.Column(db.Text, nullable=False)
    timestamp = db.Column(db.DateTime, default=datetime.utcnow)
    sender_delete = db.Column(db.Boolean, nullable=False, default=False)
    receiver_delete = db.Column(db.Boolean, nullable=False, default=False)

# with app.app_context():
#     Message.__table__.create(db.engine, checkfirst=True)

@app.route('/messages/<int:user_id>', methods=['GET'])
def get_all_messages(user_id):
    # 找出所有与该用户有消息往来的联系人id
    sent_contacts = db.session.query(Message.receiver_id).filter(
        (Message.sender_id == user_id) & (Message.sender_delete == False)
    ).distinct()

    received_contacts = db.session.query(Message.sender_id).filter(
        (Message.receiver_id == user_id) & (Message.receiver_delete == False)
    ).distinct()

    contact_ids = set([c[0] for c in sent_contacts.union(received_contacts)])

    result = {}
    for contact_id in contact_ids:
        messages = Message.query.filter(
            (
                (Message.sender_id == user_id) & (Message.receiver_id == contact_id) & (Message.sender_delete == False)
            ) | (
                (Message.sender_id == contact_id) & (Message.receiver_id == user_id) & (Message.receiver_delete == False)
            )
        ).order_by(Message.timestamp).all()

        result[contact_id] = []
        for msg in messages:
            sender = User.query.get(msg.sender_id)
            receiver = User.query.get(msg.receiver_id)

            result[contact_id].append({
                'id': msg.id,
                'sender_id': msg.sender_id,
                'receiver_id': msg.receiver_id,
                'content': msg.content,
                'timestamp': msg.timestamp.isoformat(),
                'sender_name': sender.username if sender else '未知用户',
                'receiver_name': receiver.username if receiver else '未知用户',
                'receiver_avatar': '/static/default_avatar.png',
                'sender_avatar': '/static/default_avatar.png'
            })

    return jsonify(result)


@app.route('/messages/<int:user_id>/<int:contact_id>', methods=['DELETE'])
def delete_chat_with_contact(user_id, contact_id):
    messages = Message.query.filter(
        ((Message.sender_id == user_id) & (Message.receiver_id == contact_id)) |
        ((Message.sender_id == contact_id) & (Message.receiver_id == user_id))
    ).all()

    for msg in messages:
        if msg.sender_id == user_id:
            msg.sender_delete = True
        if msg.receiver_id == user_id:
            msg.receiver_delete = True

    db.session.commit()
    return jsonify({'status': 'messages logically deleted'})



@socketio.on('send_message')
def handle_send_message(data):
    sender_id = data['sender_id']
    receiver_id = data['receiver_id']
    content = data['content']
    message = Message(sender_id=sender_id, receiver_id=receiver_id, content=content)
    db.session.add(message)
    db.session.commit()

    sender = User.query.get(sender_id)
    receiver = User.query.get(receiver_id)
    emit('receive_message', {
        'id': message.id,
        'sender_id': sender_id,
        'receiver_id': receiver_id,
        'content': content,
        'timestamp': message.timestamp.isoformat(),
        'sender_name': sender.username if sender else '未知用户',
        'receiver_name': receiver.username if receiver else  '未知用户',
        'receiver_avatar': '/static/default_avatar.png',
        'sender_avatar': '/static/default_avatar.png'
    }, broadcast=True)
    print("发送", content)


if __name__ == '__main__':
    socketio.run(app, host='0.0.0.0', port=8082,debug=True)
    # app.run(debug=True)
    CORS(app)